/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.panel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.DropMode;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree.DropLocation;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.text.Position;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.jxSwing.component.JXComponent;
import org.jxSwing.component.tree.CheckedTree;
import org.jxSwing.component.tree.node.CheckNode;
import org.jxSwing.i18n.I18N;
import org.jxUtils.check.CheckUtil;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.panel
 * @date 15/11/2014 - 21:17:36
 */
public class CheckedTreePanel extends JPanel implements JXComponent {
	
	private static final long serialVersionUID = -8098966122271978423L;
	
	private JScrollPane scrollPane;
	
	private CheckedTree checkedTree;
	
	private boolean requiredBorderEnabled = true;
	
	/**
	 * @param root
	 */
	public CheckedTreePanel(CheckNode root) {
	
		checkedTree = new CheckedTree(root);
		
		initGUI();
	}
	
	/**
	 *
	 */
	private void initGUI() {
	
		getTree().setRequiredBorderEnabled(false);
		
		setLayout(new BorderLayout());
		
		add(getScrollPane(), BorderLayout.CENTER);
	}
	
	/**
	 * Adds the specified rows (inclusive) to the selection. If the
	 * specified indices are within the viewable set of rows, or bound
	 * the viewable set of rows, then the specified indices are
	 * constrained by the viewable set of rows. If the indices are not
	 * within the viewable set of rows, or do not bound the viewable
	 * set of rows, then the selection is unchanged. For example, if
	 * the row count is {@code 10}, and this method is invoked with {@code -1, 20}, then the specified indices bounds the viewable
	 * range, and this is treated as if invoked with {@code 0, 9}. On
	 * the other hand, if this were invoked with {@code -10, -1}, then
	 * the specified indices do not bound the viewable set of rows,
	 * and the selection is unchanged.
	 * <p>
	 * The parameters are not order dependent. That is, {@code addSelectionInterval(x, y)} is equivalent to {@code addSelectionInterval(y, x)}.
	 *
	 * @param index0
	 *        the first index in the range to add to the selection
	 * @param index1
	 *        the last index in the range to add to the selection
	 */
	public void addSelectionInterval(int index0, int index1) {
	
		getTree().addSelectionInterval(index0, index1);
	}
	
	/**
	 * Adds the node identified by the specified <code>TreePath</code> to the current selection. If any component of the path isn't
	 * viewable, and <code>getExpandsSelectedPaths</code> is true it is
	 * made viewable.
	 * <p>
	 * Note that <code>JTree</code> does not allow duplicate nodes to exist as children under the same parent -- each sibling must be a unique object.
	 *
	 * @param path
	 *        the <code>TreePath</code> to add
	 */
	public void addSelectionPath(TreePath path) {
	
		getTree().addSelectionPath(path);
	}
	
	/**
	 * Adds each path in the array of paths to the current selection. If
	 * any component of any of the paths isn't viewable and <code>getExpandsSelectedPaths</code> is true, it is
	 * made viewable.
	 * <p>
	 * Note that <code>JTree</code> does not allow duplicate nodes to exist as children under the same parent -- each sibling must be a unique object.
	 *
	 * @param paths
	 *        an array of <code>TreePath</code> objects that specifies
	 *        the nodes to add
	 */
	public void addSelectionPaths(TreePath[] paths) {
	
		getTree().addSelectionPaths(paths);
	}
	
	/**
	 * Adds the path at the specified row to the current selection.
	 *
	 * @param row
	 *        an integer specifying the row of the node to add,
	 *        where 0 is the first row in the display
	 */
	public void addSelectionRow(int row) {
	
		getTree().addSelectionRow(row);
	}
	
	/**
	 * Adds the paths at each of the specified rows to the current selection.
	 *
	 * @param rows
	 *        an array of ints specifying the rows to add,
	 *        where 0 indicates the first row in the display
	 */
	public void addSelectionRows(int[] rows) {
	
		getTree().addSelectionRows(rows);
	}
	
	/**
	 * Adds a listener for <code>TreeExpansion</code> events.
	 *
	 * @param tel
	 *        a TreeExpansionListener that will be notified when
	 *        a tree node is expanded or collapsed (a "negative
	 *        expansion")
	 */
	public void addTreeExpansionListener(TreeExpansionListener tel) {
	
		getTree().addTreeExpansionListener(tel);
	}
	
	/**
	 * Adds a listener for <code>TreeSelection</code> events.
	 *
	 * @param tsl
	 *        the <code>TreeSelectionListener</code> that will be notified
	 *        when a node is selected or deselected (a "negative
	 *        selection")
	 */
	public void addTreeSelectionListener(TreeSelectionListener tsl) {
	
		getTree().addTreeSelectionListener(tsl);
	}
	
	/**
	 * Adds a listener for <code>TreeWillExpand</code> events.
	 *
	 * @param tel
	 *        a <code>TreeWillExpandListener</code> that will be notified
	 *        when a tree node will be expanded or collapsed (a "negative
	 *        expansion")
	 */
	public void addTreeWillExpandListener(TreeWillExpandListener tel) {
	
		getTree().addTreeWillExpandListener(tel);
	}
	
	/**
	 * Cancels the current editing session. Has no effect if the
	 * tree isn't being edited.
	 */
	public void cancelEditing() {
	
		getTree().cancelEditing();
	}
	
	/**
	 * Clears the selection.
	 */
	public void clearSelection() {
	
		getTree().clearSelection();
	}
	
	/**
	 * Ensures that the node identified by the specified path is
	 * collapsed and viewable.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying a node
	 */
	public void collapsePath(TreePath path) {
	
		getTree().collapsePath(path);
	}
	
	/**
	 * Ensures that the node in the specified row is collapsed.
	 * <p>
	 * If <code>row</code> is < 0 or >= <code>getRowCount</code> this will have no effect.
	 *
	 * @param row
	 *        an integer specifying a display row, where 0 is the
	 *        first row in the display
	 */
	public void collapseRow(int row) {
	
		getTree().collapseRow(row);
	}
	
	/**
	 * Called by the renderers to convert the specified value to
	 * text. This implementation returns <code>value.toString</code>, ignoring
	 * all other arguments. To control the conversion, subclass this
	 * method and use any of the arguments you need.
	 *
	 * @param value
	 *        the <code>Object</code> to convert to text
	 * @param selected
	 *        true if the node is selected
	 * @param expanded
	 *        true if the node is expanded
	 * @param leaf
	 *        true if the node is a leaf node
	 * @param row
	 *        an integer specifying the node's display row, where 0 is
	 *        the first row in the display
	 * @param hasFocus
	 *        true if the node has the focus
	 * @return the <code>String</code> representation of the node's value
	 */
	public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
	
		return getTree().convertValueToText(value, selected, expanded, leaf, row, hasFocus);
	}
	
	/**
	 * Ensures that the node identified by the specified path is
	 * expanded and viewable. If the last item in the path is a
	 * leaf, this will have no effect.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying a node
	 */
	public void expandPath(TreePath path) {
	
		getTree().expandPath(path);
	}
	
	/**
	 * Ensures that the node in the specified row is expanded and
	 * viewable.
	 * <p>
	 * If <code>row</code> is < 0 or >= <code>getRowCount</code> this will have no effect.
	 *
	 * @param row
	 *        an integer specifying a display row, where 0 is the
	 *        first row in the display
	 */
	public void expandRow(int row) {
	
		getTree().expandRow(row);
	}
	
	/**
	 * Notifies all listeners that have registered interest for
	 * notification on this event type. The event instance
	 * is lazily created using the <code>path</code> parameter.
	 *
	 * @param path
	 *        the <code>TreePath</code> indicating the node that was
	 *        collapsed
	 * @see EventListenerList
	 */
	public void fireTreeCollapsed(TreePath path) {
	
		getTree().fireTreeCollapsed(path);
	}
	
	/**
	 * Notifies all listeners that have registered interest for
	 * notification on this event type. The event instance
	 * is lazily created using the <code>path</code> parameter.
	 *
	 * @param path
	 *        the <code>TreePath</code> indicating the node that was
	 *        expanded
	 * @see EventListenerList
	 */
	public void fireTreeExpanded(TreePath path) {
	
		getTree().fireTreeExpanded(path);
	}
	
	/**
	 * Notifies all listeners that have registered interest for
	 * notification on this event type. The event instance
	 * is lazily created using the <code>path</code> parameter.
	 *
	 * @param path
	 *        the <code>TreePath</code> indicating the node that was
	 *        expanded
	 * @see EventListenerList
	 */
	public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException {
	
		getTree().fireTreeWillCollapse(path);
	}
	
	/**
	 * Notifies all listeners that have registered interest for
	 * notification on this event type. The event instance
	 * is lazily created using the <code>path</code> parameter.
	 *
	 * @param path
	 *        the <code>TreePath</code> indicating the node that was
	 *        expanded
	 * @see EventListenerList
	 */
	public void fireTreeWillExpand(TreePath path) throws ExpandVetoException {
	
		getTree().fireTreeWillExpand(path);
	}
	
	/**
	 * @param file
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	public final void fromXML(final File file) throws IOException, ParserConfigurationException, SAXException {
	
		getTree().fromXML(file);
	}
	
	/**
	 * @param xmlFile
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	public final void fromXML(final File xmlFile, final boolean showDetails, final boolean showType) throws IOException, ParserConfigurationException, SAXException {
	
		getTree().fromXML(xmlFile, showDetails, showType);
	}
	
	/**
	 * Returns the path identified as the anchor.
	 * 
	 * @return path identified as the anchor
	 * @since 1.3
	 */
	public TreePath getAnchorSelectionPath() {
	
		return getTree().getAnchorSelectionPath();
	}
	
	/**
	 * Returns the editor used to edit entries in the tree.
	 *
	 * @return the <code>TreeCellEditor</code> in use,
	 *         or <code>null</code> if the tree cannot be edited
	 */
	public TreeCellEditor getCellEditor() {
	
		return getTree().getCellEditor();
	}
	
	/**
	 * Returns the current <code>TreeCellRenderer</code> that is rendering each cell.
	 *
	 * @return the <code>TreeCellRenderer</code> that is rendering each cell
	 */
	public TreeCellRenderer getCellRenderer() {
	
		return getTree().getCellRenderer();
	}
	
	/**
	 * Returns the path to the node that is closest to x,y. If
	 * no nodes are currently viewable, or there is no model, returns <code>null</code>, otherwise it always returns a valid path. To test if
	 * the node is exactly at x, y, get the node's bounds and
	 * test x, y against that.
	 *
	 * @param x
	 *        an integer giving the number of pixels horizontally from
	 *        the left edge of the display area, minus any left margin
	 * @param y
	 *        an integer giving the number of pixels vertically from
	 *        the top of the display area, minus any top margin
	 * @return the <code>TreePath</code> for the node closest to that location, <code>null</code> if nothing is viewable or there is no model
	 * @see #getPathForLocation
	 * @see #getPathBounds
	 */
	public TreePath getClosestPathForLocation(int x, int y) {
	
		return getTree().getClosestPathForLocation(x, y);
	}
	
	/**
	 * Returns the row to the node that is closest to x,y. If no nodes
	 * are viewable or there is no model, returns -1. Otherwise,
	 * it always returns a valid row. To test if the returned object is
	 * exactly at x, y, get the bounds for the node at the returned
	 * row and test x, y against that.
	 *
	 * @param x
	 *        an integer giving the number of pixels horizontally from
	 *        the left edge of the display area, minus any left margin
	 * @param y
	 *        an integer giving the number of pixels vertically from
	 *        the top of the display area, minus any top margin
	 * @return the row closest to the location, -1 if nothing is
	 *         viewable or there is no model
	 * @see #getRowForLocation
	 * @see #getRowBounds
	 */
	public int getClosestRowForLocation(int x, int y) {
	
		return getTree().getClosestRowForLocation(x, y);
	}
	
	/**
	 * Returns whether or not automatic drag handling is enabled.
	 *
	 * @return the value of the {@code dragEnabled} property
	 * @see #setDragEnabled
	 * @since 1.4
	 */
	public boolean getDragEnabled() {
	
		return getTree().getDragEnabled();
	}
	
	/**
	 * Returns the location that this component should visually indicate
	 * as the drop location during a DnD operation over the component,
	 * or {@code null} if no location is to currently be shown.
	 * <p>
	 * This method is not meant for querying the drop location from a {@code TransferHandler}, as the drop location is only set after the {@code TransferHandler}'s <code>canImport</code> has returned and has allowed for the location to be shown.
	 * <p>
	 * When this property changes, a property change event with name "dropLocation" is fired by the component.
	 *
	 * @return the drop location
	 * @see #setDropMode
	 * @see TransferHandler#canImport(TransferHandler.TransferSupport)
	 * @since 1.6
	 */
	public final DropLocation getDropLocation() {
	
		return getTree().getDropLocation();
	}
	
	/**
	 * Returns the drop mode for this component.
	 *
	 * @return the drop mode for this component
	 * @see #setDropMode
	 * @since 1.6
	 */
	public final DropMode getDropMode() {
	
		return getTree().getDropMode();
	}
	
	/**
	 * Returns the path to the element that is currently being edited.
	 *
	 * @return the <code>TreePath</code> for the node being edited
	 */
	public TreePath getEditingPath() {
	
		return getTree().getEditingPath();
	}
	
	/**
	 * Returns an <code>Enumeration</code> of the descendants of the
	 * path <code>parent</code> that
	 * are currently expanded. If <code>parent</code> is not currently
	 * expanded, this will return <code>null</code>.
	 * If you expand/collapse nodes while
	 * iterating over the returned <code>Enumeration</code> this may not return all
	 * the expanded paths, or may return paths that are no longer expanded.
	 *
	 * @param parent
	 *        the path which is to be examined
	 * @return an <code>Enumeration</code> of the descendents of <code>parent</code>, or <code>null</code> if <code>parent</code> is not currently expanded
	 */
	public Enumeration<TreePath> getExpandedDescendants(TreePath parent) {
	
		return getTree().getExpandedDescendants(parent);
	}
	
	/**
	 * Returns the <code>expandsSelectedPaths</code> property.
	 * 
	 * @return true if selection changes result in the parent path being
	 *         expanded
	 * @since 1.3
	 * @see #setExpandsSelectedPaths
	 */
	public boolean getExpandsSelectedPaths() {
	
		return getTree().getExpandsSelectedPaths();
	}
	
	@Override
	public int getIndex() {
	
		return getTree().getIndex();
	}
	
	/**
	 * Returns the indicator that tells what happens when editing is
	 * interrupted.
	 *
	 * @return the indicator that tells what happens when editing is
	 *         interrupted
	 * @see #setInvokesStopCellEditing
	 */
	public boolean getInvokesStopCellEditing() {
	
		return getTree().getInvokesStopCellEditing();
	}
	
	/**
	 * Returns the last path component of the selected path. This is
	 * a convenience method for {@code getSelectionModel().getSelectionPath().getLastPathComponent()}.
	 * This is typically only useful if the selection has one path.
	 *
	 * @return the last path component of the selected path, or <code>null</code> if nothing is selected
	 * @see TreePath#getLastPathComponent
	 */
	public Object getLastSelectedPathComponent() {
	
		return getTree().getLastSelectedPathComponent();
	}
	
	/**
	 * Returns the path identified as the lead.
	 * 
	 * @return path identified as the lead
	 */
	public TreePath getLeadSelectionPath() {
	
		return getTree().getLeadSelectionPath();
	}
	
	/**
	 * Returns the row index corresponding to the lead path.
	 *
	 * @return an integer giving the row index of the lead path,
	 *         where 0 is the first row in the display; or -1
	 *         if <code>leadPath</code> is <code>null</code>
	 */
	public int getLeadSelectionRow() {
	
		return getTree().getLeadSelectionRow();
	}
	
	/**
	 * Returns the largest selected row. If the selection is empty, or
	 * none of the selected paths are viewable, {@code -1} is returned.
	 *
	 * @return the largest selected row
	 */
	public int getMaxSelectionRow() {
	
		return getTree().getMaxSelectionRow();
	}
	
	/**
	 * Returns the smallest selected row. If the selection is empty, or
	 * none of the selected paths are viewable, {@code -1} is returned.
	 *
	 * @return the smallest selected row
	 */
	public int getMinSelectionRow() {
	
		return getTree().getMinSelectionRow();
	}
	
	/**
	 * Returns the <code>TreeModel</code> that is providing the data.
	 *
	 * @return the <code>TreeModel</code> that is providing the data
	 */
	public TreeModel getModel() {
	
		return getTree().getModel();
	}
	
	/**
	 * Returns the TreePath to the next tree element that
	 * begins with a prefix. To handle the conversion of a <code>TreePath</code> into a String, <code>convertValueToText</code> is used.
	 *
	 * @param prefix
	 *        the string to test for a match
	 * @param startingRow
	 *        the row for starting the search
	 * @param bias
	 *        the search direction, either
	 *        Position.Bias.Forward or Position.Bias.Backward.
	 * @return the TreePath of the next tree element that
	 *         starts with the prefix; otherwise null
	 * @exception IllegalArgumentException
	 *            if prefix is null
	 *            or startingRow is out of bounds
	 * @since 1.4
	 */
	public TreePath getNextMatch(String prefix, int startingRow, Position.Bias bias) {
	
		return getTree().getNextMatch(prefix, startingRow, bias);
	}
	
	/**
	 * This simple method returns a displayable string given a NodeType
	 * 
	 * @param node
	 * @return type
	 */
	public final String getNodeType(final Node node) {
	
		return getTree().getNodeType(node);
	}
	
	/**
	 * Returns the <code>Rectangle</code> that the specified node will be drawn
	 * into. Returns <code>null</code> if any component in the path is hidden
	 * (under a collapsed parent).
	 * <p>
	 * Note:<br>
	 * This method returns a valid rectangle, even if the specified node is not currently displayed.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying the node
	 * @return the <code>Rectangle</code> the node is drawn in,
	 *         or <code>null</code>
	 */
	public Rectangle getPathBounds(TreePath path) {
	
		return getTree().getPathBounds(path);
	}
	
	/**
	 * Returns the path for the node at the specified location.
	 *
	 * @param x
	 *        an integer giving the number of pixels horizontally from
	 *        the left edge of the display area, minus any left margin
	 * @param y
	 *        an integer giving the number of pixels vertically from
	 *        the top of the display area, minus any top margin
	 * @return the <code>TreePath</code> for the node at that location
	 */
	public TreePath getPathForLocation(int x, int y) {
	
		return getTree().getPathForLocation(x, y);
	}
	
	/**
	 * Returns the path for the specified row. If <code>row</code> is
	 * not visible, or a {@code TreeUI} has not been set, <code>null</code> is returned.
	 *
	 * @param row
	 *        an integer specifying a row
	 * @return the <code>TreePath</code> to the specified node, <code>null</code> if <code>row < 0</code> or <code>row >= getRowCount()</code>
	 */
	public TreePath getPathForRow(int row) {
	
		return getTree().getPathForRow(row);
	}
	
	/**
	 * Returns the <code>Rectangle</code> that the node at the specified row is
	 * drawn in.
	 *
	 * @param row
	 *        the row to be drawn, where 0 is the first row in the
	 *        display
	 * @return the <code>Rectangle</code> the node is drawn in
	 */
	public Rectangle getRowBounds(int row) {
	
		return getTree().getRowBounds(row);
	}
	
	/**
	 * Returns the number of viewable nodes. A node is viewable if all of its
	 * parents are expanded. The root is only included in this count if {@code isRootVisible()} is {@code true}. This returns {@code 0} if
	 * the UI has not been set.
	 *
	 * @return the number of viewable nodes
	 */
	public int getRowCount() {
	
		return getTree().getRowCount();
	}
	
	/**
	 * Returns the row for the specified location.
	 *
	 * @param x
	 *        an integer giving the number of pixels horizontally from
	 *        the left edge of the display area, minus any left margin
	 * @param y
	 *        an integer giving the number of pixels vertically from
	 *        the top of the display area, minus any top margin
	 * @return the row corresponding to the location, or -1 if the
	 *         location is not within the bounds of a displayed cell
	 * @see #getClosestRowForLocation
	 */
	public int getRowForLocation(int x, int y) {
	
		return getTree().getRowForLocation(x, y);
	}
	
	/**
	 * Returns the row that displays the node identified by the specified
	 * path.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying a node
	 * @return an integer specifying the display row, where 0 is the first
	 *         row in the display, or -1 if any of the elements in path
	 *         are hidden under a collapsed parent.
	 */
	public int getRowForPath(TreePath path) {
	
		return getTree().getRowForPath(path);
	}
	
	/**
	 * Returns the height of each row. If the returned value is less than
	 * or equal to 0 the height for each row is determined by the
	 * renderer.
	 */
	public int getRowHeight() {
	
		return getTree().getRowHeight();
	}
	
	/**
	 * @return the scrollPane
	 */
	public final JScrollPane getScrollPane() {
	
		if(scrollPane == null) {
			scrollPane = new JScrollPane(getTree());
		}
		return scrollPane;
	}
	
	//
	// The following are convenience methods that get forwarded to the
	// current TreeUI.
	//
	
	/**
	 * Returns the value of the <code>scrollsOnExpand</code> property.
	 *
	 * @return the value of the <code>scrollsOnExpand</code> property
	 */
	public boolean getScrollsOnExpand() {
	
		return getTree().getScrollsOnExpand();
	}
	
	/**
	 * Returns the number of nodes selected.
	 *
	 * @return the number of nodes selected
	 */
	public int getSelectionCount() {
	
		return getTree().getSelectionCount();
	}
	
	/**
	 * Returns the model for selections. This should always return a
	 * non-<code>null</code> value. If you don't want to allow anything
	 * to be selected
	 * set the selection model to <code>null</code>, which forces an empty
	 * selection model to be used.
	 *
	 * @see #setSelectionModel
	 */
	public TreeSelectionModel getSelectionModel() {
	
		return getTree().getSelectionModel();
	}
	
	/**
	 * Returns the path to the first selected node.
	 *
	 * @return the <code>TreePath</code> for the first selected node,
	 *         or <code>null</code> if nothing is currently selected
	 */
	public TreePath getSelectionPath() {
	
		return getTree().getSelectionPath();
	}
	
	/**
	 * Returns the paths of all selected values.
	 *
	 * @return an array of <code>TreePath</code> objects indicating the selected
	 *         nodes, or <code>null</code> if nothing is currently selected
	 */
	public TreePath[] getSelectionPaths() {
	
		return getTree().getSelectionPaths();
	}
	
	/**
	 * Returns all of the currently selected rows. This method is simply
	 * forwarded to the <code>TreeSelectionModel</code>.
	 * If nothing is selected <code>null</code> or an empty array will
	 * be returned, based on the <code>TreeSelectionModel</code> implementation.
	 *
	 * @return an array of integers that identifies all currently selected rows
	 *         where 0 is the first row in the display
	 */
	public int[] getSelectionRows() {
	
		return getTree().getSelectionRows();
	}
	
	/**
	 * Returns the value of the <code>showsRootHandles</code> property.
	 *
	 * @return the value of the <code>showsRootHandles</code> property
	 * @see #showsRootHandles
	 */
	public boolean getShowsRootHandles() {
	
		return getTree().getShowsRootHandles();
	}
	
	/**
	 * Returns the number of mouse clicks needed to expand or close a node.
	 *
	 * @return number of mouse clicks before node is expanded
	 * @since 1.3
	 */
	public int getToggleClickCount() {
	
		return getTree().getToggleClickCount();
	}
	
	/**
	 * Overrides <code>JComponent</code>'s <code>getToolTipText</code> method in order to allow
	 * renderer's tips to be used if it has text set.
	 * <p>
	 * NOTE: For <code>JTree</code> to properly display tooltips of its renderers, <code>JTree</code> must be a registered component with the <code>ToolTipManager</code>. This can be done by invoking <code>ToolTipManager.sharedInstance().registerComponent(tree)</code>. This is not done automatically!
	 *
	 * @param event
	 *        the <code>MouseEvent</code> that initiated the <code>ToolTip</code> display
	 * @return a string containing the tooltip or <code>null</code> if <code>event</code> is null
	 */
	public String getToolTipText(MouseEvent event) {
	
		return getTree().getToolTipText(event);
	}
	
	/**
	 * @return the tree
	 */
	public final CheckedTree getTree() {
	
		return checkedTree;
	}
	
	/**
	 * Returns an array of all the <code>TreeExpansionListener</code>s added
	 * to this JTree with addTreeExpansionListener().
	 *
	 * @return all of the <code>TreeExpansionListener</code>s added or an empty
	 *         array if no listeners have been added
	 * @since 1.4
	 */
	public TreeExpansionListener[] getTreeExpansionListeners() {
	
		return getTree().getTreeExpansionListeners();
	}
	
	/**
	 * Returns an array of all the <code>TreeSelectionListener</code>s added
	 * to this JTree with addTreeSelectionListener().
	 *
	 * @return all of the <code>TreeSelectionListener</code>s added or an empty
	 *         array if no listeners have been added
	 * @since 1.4
	 */
	public TreeSelectionListener[] getTreeSelectionListeners() {
	
		return getTree().getTreeSelectionListeners();
	}
	
	/**
	 * Returns an array of all the <code>TreeWillExpandListener</code>s added
	 * to this JTree with addTreeWillExpandListener().
	 *
	 * @return all of the <code>TreeWillExpandListener</code>s added or an empty
	 *         array if no listeners have been added
	 * @since 1.4
	 */
	public TreeWillExpandListener[] getTreeWillExpandListeners() {
	
		return getTree().getTreeWillExpandListeners();
	}
	
	/**
	 * Returns the number of rows that are displayed in the display area.
	 *
	 * @return the number of rows displayed
	 */
	public int getVisibleRowCount() {
	
		return getTree().getVisibleRowCount();
	}
	
	/**
	 * Returns true if the node identified by the path has ever been
	 * expanded.
	 * 
	 * @return true if the <code>path</code> has ever been expanded
	 */
	public boolean hasBeenExpanded(TreePath path) {
	
		return getTree().hasBeenExpanded(path);
	}
	
	@Override
	public boolean isAtributte() {
	
		return getTree().isAtributte();
	}
	
	/**
	 * Returns true if the node at the specified display row is collapsed.
	 *
	 * @param row
	 *        the row to check, where 0 is the first row in the
	 *        display
	 * @return true if the node is currently collapsed, otherwise false
	 */
	public boolean isCollapsed(int row) {
	
		return getTree().isCollapsed(row);
	}
	
	/**
	 * Returns true if the value identified by path is currently collapsed,
	 * this will return false if any of the values in path are currently
	 * not being displayed.
	 *
	 * @param path
	 *        the <code>TreePath</code> to check
	 * @return true if any of the nodes in the node's path are collapsed,
	 *         false if all nodes in the path are expanded
	 */
	public boolean isCollapsed(TreePath path) {
	
		return getTree().isCollapsed(path);
	}
	
	/**
	 * Returns true if the tree is editable.
	 *
	 * @return true if the tree is editable
	 */
	public boolean isEditable() {
	
		return getTree().isEditable();
	}
	
	/**
	 * Returns true if the tree is being edited. The item that is being
	 * edited can be obtained using <code>getSelectionPath</code>.
	 *
	 * @return true if the user is currently editing a node
	 * @see #getSelectionPath
	 */
	public boolean isEditing() {
	
		return getTree().isEditing();
	}
	
	/**
	 * Returns true if the node at the specified display row is currently
	 * expanded.
	 *
	 * @param row
	 *        the row to check, where 0 is the first row in the
	 *        display
	 * @return true if the node is currently expanded, otherwise false
	 */
	public boolean isExpanded(int row) {
	
		return getTree().isExpanded(row);
	}
	
	/**
	 * Returns true if the node identified by the path is currently expanded,
	 *
	 * @param path
	 *        the <code>TreePath</code> specifying the node to check
	 * @return false if any of the nodes in the node's path are collapsed,
	 *         true if all nodes in the path are expanded
	 */
	public boolean isExpanded(TreePath path) {
	
		return getTree().isExpanded(path);
	}
	
	/**
	 * Returns true if the height of each display row is a fixed size.
	 *
	 * @return true if the height of each row is a fixed size
	 */
	public boolean isFixedRowHeight() {
	
		return getTree().isFixedRowHeight();
	}
	
	/**
	 * Returns true if the tree is configured for a large model.
	 *
	 * @return true if a large model is suggested
	 * @see #largeModel
	 */
	public boolean isLargeModel() {
	
		return getTree().isLargeModel();
	}
	
	/**
	 * Returns <code>isEditable</code>. This is invoked from the UI before
	 * editing begins to insure that the given path can be edited. This
	 * is provided as an entry point for subclassers to add filtered
	 * editing without having to resort to creating a new editor.
	 *
	 * @return true if every parent node and the node itself is editable
	 * @see #isEditable
	 */
	public boolean isPathEditable(TreePath path) {
	
		return getTree().isPathEditable(path);
	}
	
	/**
	 * Returns true if the item identified by the path is currently selected.
	 *
	 * @param path
	 *        a <code>TreePath</code> identifying a node
	 * @return true if the node is selected
	 */
	public boolean isPathSelected(TreePath path) {
	
		return getTree().isPathSelected(path);
	}
	
	@Override
	public boolean isRequired() {
	
		return getTree().isRequired();
	}
	
	@Override
	public boolean isRequiredBorderEnabled() {
	
		return requiredBorderEnabled;
	}
	
	/**
	 * Returns true if the root node of the tree is displayed.
	 *
	 * @return true if the root node of the tree is displayed
	 * @see #rootVisible
	 */
	public boolean isRootVisible() {
	
		return getTree().isRootVisible();
	}
	
	/**
	 * Returns true if the node identified by row is selected.
	 *
	 * @param row
	 *        an integer specifying a display row, where 0 is the first
	 *        row in the display
	 * @return true if the node is selected
	 */
	public boolean isRowSelected(int row) {
	
		return getTree().isRowSelected(row);
	}
	
	/**
	 * Returns true if the selection is currently empty.
	 *
	 * @return true if the selection is currently empty
	 */
	public boolean isSelectionEmpty() {
	
		return getTree().isSelectionEmpty();
	}
	
	/**
	 * Returns true if the value identified by path is currently viewable,
	 * which means it is either the root or all of its parents are expanded.
	 * Otherwise, this method returns false.
	 *
	 * @return true if the node is viewable, otherwise false
	 */
	public boolean isVisible(TreePath path) {
	
		return getTree().isVisible(path);
	}
	
	/**
	 * Ensures that the node identified by path is currently viewable.
	 *
	 * @param path
	 *        the <code>TreePath</code> to make visible
	 */
	public void makeVisible(TreePath path) {
	
		getTree().makeVisible(path);
	}
	
	/**
	 * Removes the specified rows (inclusive) from the selection. If
	 * the specified indices are within the viewable set of rows, or bound
	 * the viewable set of rows, then the specified indices are constrained by
	 * the viewable set of rows. If the specified indices are not within the
	 * viewable set of rows, or do not bound the viewable set of rows, then
	 * the selection is unchanged. For example, if the row count is {@code 10}, and this method is invoked with {@code -1, 20}, then the
	 * specified range bounds the viewable range, and this is treated as
	 * if invoked with {@code 0, 9}. On the other hand, if this were
	 * invoked with {@code -10, -1}, then the specified range does not
	 * bound the viewable set of rows, and the selection is unchanged.
	 * <p>
	 * The parameters are not order dependent. That is, {@code removeSelectionInterval(x, y)} is equivalent to {@code removeSelectionInterval(y, x)}.
	 *
	 * @param index0
	 *        the first row to remove from the selection
	 * @param index1
	 *        the last row to remove from the selection
	 */
	public void removeSelectionInterval(int index0, int index1) {
	
		getTree().removeSelectionInterval(index0, index1);
	}
	
	/**
	 * Removes the node identified by the specified path from the current
	 * selection.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying a node
	 */
	public void removeSelectionPath(TreePath path) {
	
		getTree().removeSelectionPath(path);
	}
	
	/**
	 * Removes the nodes identified by the specified paths from the
	 * current selection.
	 *
	 * @param paths
	 *        an array of <code>TreePath</code> objects that
	 *        specifies the nodes to remove
	 */
	public void removeSelectionPaths(TreePath[] paths) {
	
		getTree().removeSelectionPaths(paths);
	}
	
	/**
	 * Removes the row at the index <code>row</code> from the current
	 * selection.
	 *
	 * @param row
	 *        the row to remove
	 */
	public void removeSelectionRow(int row) {
	
		getTree().removeSelectionRow(row);
	}
	
	/**
	 * Removes the rows that are selected at each of the specified
	 * rows.
	 *
	 * @param rows
	 *        an array of ints specifying display rows, where 0 is
	 *        the first row in the display
	 */
	public void removeSelectionRows(int[] rows) {
	
		getTree().removeSelectionRows(rows);
	}
	
	/**
	 * Removes a listener for <code>TreeExpansion</code> events.
	 *
	 * @param tel
	 *        the <code>TreeExpansionListener</code> to remove
	 */
	public void removeTreeExpansionListener(TreeExpansionListener tel) {
	
		getTree().removeTreeExpansionListener(tel);
	}
	
	/**
	 * Removes a <code>TreeSelection</code> listener.
	 *
	 * @param tsl
	 *        the <code>TreeSelectionListener</code> to remove
	 */
	public void removeTreeSelectionListener(TreeSelectionListener tsl) {
	
		getTree().removeTreeSelectionListener(tsl);
	}
	
	/**
	 * Removes a listener for <code>TreeWillExpand</code> events.
	 *
	 * @param tel
	 *        the <code>TreeWillExpandListener</code> to remove
	 */
	public void removeTreeWillExpandListener(TreeWillExpandListener tel) {
	
		getTree().removeTreeWillExpandListener(tel);
	}
	
	/**
	 * Makes sure all the path components in path are expanded (except
	 * for the last path component) and scrolls so that the
	 * node identified by the path is displayed. Only works when this <code>JTree</code> is contained in a <code>JScrollPane</code>.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying the node to
	 *        bring into view
	 */
	public void scrollPathToVisible(TreePath path) {
	
		getTree().scrollPathToVisible(path);
	}
	
	/**
	 * Scrolls the item identified by row until it is displayed. The minimum
	 * of amount of scrolling necessary to bring the row into view
	 * is performed. Only works when this <code>JTree</code> is contained in a <code>JScrollPane</code>.
	 *
	 * @param row
	 *        an integer specifying the row to scroll, where 0 is the
	 *        first row in the display
	 */
	public void scrollRowToVisible(int row) {
	
		getTree().scrollRowToVisible(row);
	}
	
	/**
	 * Sets the path identified as the anchor.
	 * The anchor is not maintained by <code>JTree</code>, rather the UI will
	 * update it.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newPath
	 *        the new anchor path
	 * @since 1.3
	 * @beaninfo
	 *           bound: true
	 *           description: Anchor selection path
	 */
	public void setAnchorSelectionPath(TreePath newPath) {
	
		getTree().setAnchorSelectionPath(newPath);
	}
	
	@Override
	public void setAtributte(final boolean atributte) {
	
		getTree().setAtributte(atributte);
	}
	
	/**
	 * Sets the cell editor. A <code>null</code> value implies that the
	 * tree cannot be edited. If this represents a change in the <code>cellEditor</code>, the <code>propertyChange</code> method is invoked on all listeners.
	 * <p>
	 * This is a bound property.
	 *
	 * @param cellEditor
	 *        the <code>TreeCellEditor</code> to use
	 * @beaninfo
	 *           bound: true
	 *           description: The cell editor. A null value implies the tree
	 *           cannot be edited.
	 */
	public void setCellEditor(TreeCellEditor cellEditor) {
	
		getTree().setCellEditor(cellEditor);
	}
	
	/**
	 * Sets the <code>TreeCellRenderer</code> that will be used to
	 * draw each cell.
	 * <p>
	 * This is a bound property.
	 *
	 * @param x
	 *        the <code>TreeCellRenderer</code> that is to render each cell
	 * @beaninfo
	 *           bound: true
	 *           description: The TreeCellRenderer that will be used to draw
	 *           each cell.
	 */
	public void setCellRenderer(TreeCellRenderer x) {
	
		getTree().setCellRenderer(x);
	}
	
	/**
	 * Turns on or off automatic drag handling. In order to enable automatic
	 * drag handling, this property should be set to {@code true}, and the
	 * tree's {@code TransferHandler} needs to be {@code non-null}.
	 * The default value of the {@code dragEnabled} property is {@code false}.
	 * <p>
	 * The job of honoring this property, and recognizing a user drag gesture, lies with the look and feel implementation, and in particular, the tree's {@code TreeUI}. When automatic drag handling is enabled, most look and feels (including those that subclass {@code BasicLookAndFeel}) begin a drag and drop operation whenever the user presses the mouse button over an item and then moves the mouse a few pixels. Setting this property to {@code true} can therefore have a subtle effect on how selections behave.
	 * <p>
	 * If a look and feel is used that ignores this property, you can still begin a drag and drop operation by calling {@code exportAsDrag} on the tree's {@code TransferHandler}.
	 *
	 * @param b
	 *        whether or not to enable automatic drag handling
	 * @exception HeadlessException
	 *            if <code>b</code> is <code>true</code> and <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
	 * @see java.awt.GraphicsEnvironment#isHeadless
	 * @see #getDragEnabled
	 * @see #setTransferHandler
	 * @see TransferHandler
	 * @since 1.4
	 * @beaninfo
	 *           description: determines whether automatic drag handling is enabled
	 *           bound: false
	 */
	public void setDragEnabled(boolean b) {
	
		getTree().setDragEnabled(b);
	}
	
	/**
	 * Sets the drop mode for this component. For backward compatibility,
	 * the default for this property is <code>DropMode.USE_SELECTION</code>.
	 * Usage of one of the other modes is recommended, however, for an
	 * improved user experience. <code>DropMode.ON</code>, for instance,
	 * offers similar behavior of showing items as selected, but does so without
	 * affecting the actual selection in the tree.
	 * <p>
	 * <code>JTree</code> supports the following drop modes:
	 * <ul>
	 * <li><code>DropMode.USE_SELECTION</code></li>
	 * <li><code>DropMode.ON</code></li>
	 * <li><code>DropMode.INSERT</code></li>
	 * <li><code>DropMode.ON_OR_INSERT</code></li>
	 * </ul>
	 * <p>
	 * The drop mode is only meaningful if this component has a <code>TransferHandler</code> that accepts drops.
	 *
	 * @param dropMode
	 *        the drop mode to use
	 * @throws IllegalArgumentException
	 *         if the drop mode is unsupported
	 *         or <code>null</code>
	 * @see #getDropMode
	 * @see #getDropLocation
	 * @see #setTransferHandler
	 * @see TransferHandler
	 * @since 1.6
	 */
	public final void setDropMode(DropMode dropMode) {
	
		getTree().setDropMode(dropMode);
	}
	
	/**
	 * Determines whether the tree is editable. Fires a property
	 * change event if the new setting is different from the existing
	 * setting.
	 * <p>
	 * This is a bound property.
	 *
	 * @param flag
	 *        a boolean value, true if the tree is editable
	 * @beaninfo
	 *           bound: true
	 *           description: Whether the tree is editable.
	 */
	public void setEditable(boolean flag) {
	
		getTree().setEditable(flag);
	}
	
	/**
	 * Configures the <code>expandsSelectedPaths</code> property. If
	 * true, any time the selection is changed, either via the <code>TreeSelectionModel</code>, or the cover methods provided by <code>JTree</code>, the <code>TreePath</code>s parents will be
	 * expanded to make them visible (visible meaning the parent path is
	 * expanded, not necessarily in the visible rectangle of the <code>JTree</code>). If false, when the selection
	 * changes the nodes parent is not made visible (all its parents expanded).
	 * This is useful if you wish to have your selection model maintain paths
	 * that are not always visible (all parents expanded).
	 * <p>
	 * This is a bound property.
	 *
	 * @param newValue
	 *        the new value for <code>expandsSelectedPaths</code>
	 * @since 1.3
	 * @beaninfo
	 *           bound: true
	 *           description: Indicates whether changes to the selection should make
	 *           the parent of the path visible.
	 */
	public void setExpandsSelectedPaths(boolean newValue) {
	
		getTree().setExpandsSelectedPaths(newValue);
	}
	
	/**
	 * @param iconsMap
	 *        Hashtable< label, icon >
	 */
	public final void setIconsMap(final Hashtable<String, Icon> iconsMap) {
	
		getTree().setIconsMap(iconsMap);
	}
	
	@Override
	public void setIndex(final int index) {
	
		getTree().setIndex(index);
	}
	
	/**
	 * Determines what happens when editing is interrupted by selecting
	 * another node in the tree, a change in the tree's data, or by some
	 * other means. Setting this property to <code>true</code> causes the
	 * changes to be automatically saved when editing is interrupted.
	 * <p>
	 * Fires a property change for the INVOKES_STOP_CELL_EDITING_PROPERTY.
	 *
	 * @param newValue
	 *        true means that <code>stopCellEditing</code> is invoked
	 *        when editing is interrupted, and data is saved; false means that <code>cancelCellEditing</code> is invoked, and changes are lost
	 * @beaninfo
	 *           bound: true
	 *           description: Determines what happens when editing is interrupted,
	 *           selecting another node in the tree, a change in the
	 *           tree's data, or some other means.
	 */
	public void setInvokesStopCellEditing(boolean newValue) {
	
		getTree().setInvokesStopCellEditing(newValue);
	}
	
	/**
	 * Specifies whether the UI should use a large model.
	 * (Not all UIs will implement this.) Fires a property change
	 * for the LARGE_MODEL_PROPERTY.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newValue
	 *        true to suggest a large model to the UI
	 * @see #largeModel
	 * @beaninfo
	 *           bound: true
	 *           description: Whether the UI should use a
	 *           large model.
	 */
	public void setLargeModel(boolean newValue) {
	
		getTree().setLargeModel(newValue);
	}
	
	/**
	 * Sets the path identifies as the lead. The lead may not be selected.
	 * The lead is not maintained by <code>JTree</code>,
	 * rather the UI will update it.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newPath
	 *        the new lead path
	 * @since 1.3
	 * @beaninfo
	 *           bound: true
	 *           description: Lead selection path
	 */
	public void setLeadSelectionPath(TreePath newPath) {
	
		getTree().setLeadSelectionPath(newPath);
	}
	
	/**
	 * Sets the <code>TreeModel</code> that will provide the data.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newModel
	 *        the <code>TreeModel</code> that is to provide the data
	 * @beaninfo
	 *           bound: true
	 *           description: The TreeModel that will provide the data.
	 */
	public void setModel(TreeModel newModel) {
	
		getTree().setModel(newModel);
	}
	
	@Override
	public void setName(final String name) {
	
		super.setName(name);
		
		getTree().setName(name);
		
		setRequired(isRequired());
	}
	
	@Override
	public void setRequired(final boolean required) {
	
		getTree().setRequired(required);
		
		//
		if(required) {
			
			//
			if(isRequiredBorderEnabled()) {
				
				setBorder(new LineBorder(Color.RED));
			}
			
			//
			if(CheckUtil.isNullOrAbsoluteEmpty(getName())) {
				
				setToolTipText(I18N.component().requiredThis());
				
			}else {
				
				setToolTipText(I18N.component().requiredField(getName()));
			}
			
		}else {
			
			setBorder(UIManager.getBorder("Panel.border"));
			setToolTipText(null);
		}
	}
	
	@Override
	public void setRequiredBorderEnabled(final boolean requiredBorderEnabled) {
	
		this.requiredBorderEnabled = requiredBorderEnabled;
	}
	
	/**
	 * Determines whether or not the root node from
	 * the <code>TreeModel</code> is visible.
	 * <p>
	 * This is a bound property.
	 *
	 * @param rootVisible
	 *        true if the root node of the tree is to be displayed
	 * @see #rootVisible
	 * @beaninfo
	 *           bound: true
	 *           description: Whether or not the root node
	 *           from the TreeModel is visible.
	 */
	public void setRootVisible(boolean rootVisible) {
	
		getTree().setRootVisible(rootVisible);
	}
	
	/**
	 * Sets the height of each cell, in pixels. If the specified value
	 * is less than or equal to zero the current cell renderer is
	 * queried for each row's height.
	 * <p>
	 * This is a bound property.
	 *
	 * @param rowHeight
	 *        the height of each cell, in pixels
	 * @beaninfo
	 *           bound: true
	 *           description: The height of each cell.
	 */
	public void setRowHeight(int rowHeight) {
	
		getTree().setRowHeight(rowHeight);
	}
	
	/**
	 * Sets the <code>scrollsOnExpand</code> property,
	 * which determines whether the
	 * tree might scroll to show previously hidden children.
	 * If this property is <code>true</code> (the default),
	 * when a node expands
	 * the tree can use scrolling to make
	 * the maximum possible number of the node's descendants visible.
	 * In some look and feels, trees might not need to scroll when expanded;
	 * those look and feels will ignore this property.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newValue
	 *        <code>false</code> to disable scrolling on expansion; <code>true</code> to enable it
	 * @see #getScrollsOnExpand
	 * @beaninfo
	 *           bound: true
	 *           description: Indicates if a node descendant should be scrolled when expanded.
	 */
	public void setScrollsOnExpand(boolean newValue) {
	
		getTree().setScrollsOnExpand(newValue);
	}
	
	/**
	 * Selects the rows in the specified interval (inclusive). If
	 * the specified indices are within the viewable set of rows, or bound
	 * the viewable set of rows, then the specified rows are constrained by
	 * the viewable set of rows. If the specified indices are not within the
	 * viewable set of rows, or do not bound the viewable set of rows, then
	 * the selection is cleared. For example, if the row count is {@code 10}, and this method is invoked with {@code -1, 20}, then the
	 * specified indices bounds the viewable range, and this is treated as
	 * if invoked with {@code 0, 9}. On the other hand, if this were
	 * invoked with {@code -10, -1}, then the specified indices do not
	 * bound the viewable set of rows, and the selection is cleared.
	 * <p>
	 * The parameters are not order dependent. That is, {@code setSelectionInterval(x, y)} is equivalent to {@code setSelectionInterval(y, x)}.
	 *
	 * @param index0
	 *        the first index in the range to select
	 * @param index1
	 *        the last index in the range to select
	 */
	public void setSelectionInterval(int index0, int index1) {
	
		getTree().setSelectionInterval(index0, index1);
	}
	
	/**
	 * Sets the selection model, which must be one of SINGLE_TREE_SELECTION,
	 * CONTIGUOUS_TREE_SELECTION or DISCONTIGUOUS_TREE_SELECTION.
	 * <p>
	 * This may change the selection if the current selection is not valid for the new mode. For example, if three TreePaths are selected when the mode is changed to <code>SINGLE_TREE_SELECTION</code>, only one TreePath will remain selected. It is up to the particular implementation to decide what TreePath remains selected.
	 */
	public final void setSelectionMode(final int mode) {
	
		getTree().setSelectionMode(mode);
	}
	
	/**
	 * Sets the tree's selection model. When a <code>null</code> value is
	 * specified an empty <code>selectionModel</code> is used, which does not allow selections.
	 * <p>
	 * This is a bound property.
	 *
	 * @param selectionModel
	 *        the <code>TreeSelectionModel</code> to use,
	 *        or <code>null</code> to disable selections
	 * @see TreeSelectionModel
	 * @beaninfo
	 *           bound: true
	 *           description: The tree's selection model.
	 */
	public void setSelectionModel(TreeSelectionModel selectionModel) {
	
		getTree().setSelectionModel(selectionModel);
	}
	
	/**
	 * Selects the node identified by the specified path. If any
	 * component of the path is hidden (under a collapsed node), and <code>getExpandsSelectedPaths</code> is true it is
	 * exposed (made viewable).
	 *
	 * @param path
	 *        the <code>TreePath</code> specifying the node to select
	 */
	public void setSelectionPath(TreePath path) {
	
		getTree().setSelectionPath(path);
	}
	
	/**
	 * Selects the nodes identified by the specified array of paths.
	 * If any component in any of the paths is hidden (under a collapsed
	 * node), and <code>getExpandsSelectedPaths</code> is true
	 * it is exposed (made viewable).
	 *
	 * @param paths
	 *        an array of <code>TreePath</code> objects that specifies
	 *        the nodes to select
	 */
	public void setSelectionPaths(TreePath[] paths) {
	
		getTree().setSelectionPaths(paths);
	}
	
	/**
	 * Selects the node at the specified row in the display.
	 *
	 * @param row
	 *        the row to select, where 0 is the first row in
	 *        the display
	 */
	public void setSelectionRow(int row) {
	
		getTree().setSelectionRow(row);
	}
	
	/**
	 * Selects the nodes corresponding to each of the specified rows
	 * in the display. If a particular element of <code>rows</code> is
	 * < 0 or >= <code>getRowCount</code>, it will be ignored.
	 * If none of the elements
	 * in <code>rows</code> are valid rows, the selection will
	 * be cleared. That is it will be as if <code>clearSelection</code> was invoked.
	 *
	 * @param rows
	 *        an array of ints specifying the rows to select,
	 *        where 0 indicates the first row in the display
	 */
	public void setSelectionRows(int[] rows) {
	
		getTree().setSelectionRows(rows);
	}
	
	/**
	 * Sets the value of the <code>showsRootHandles</code> property,
	 * which specifies whether the node handles should be displayed.
	 * The default value of this property depends on the constructor
	 * used to create the <code>JTree</code>.
	 * Some look and feels might not support handles;
	 * they will ignore this property.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newValue
	 *        <code>true</code> if root handles should be displayed;
	 *        otherwise, <code>false</code>
	 * @see #showsRootHandles
	 * @see #getShowsRootHandles
	 * @beaninfo
	 *           bound: true
	 *           description: Whether the node handles are to be
	 *           displayed.
	 */
	public void setShowsRootHandles(boolean newValue) {
	
		getTree().setShowsRootHandles(newValue);
	}
	
	/**
	 * Sets the number of mouse clicks before a node will expand or close.
	 * The default is two.
	 * <p>
	 * This is a bound property.
	 *
	 * @since 1.3
	 * @beaninfo
	 *           bound: true
	 *           description: Number of clicks before a node will expand/collapse.
	 */
	public void setToggleClickCount(int clickCount) {
	
		getTree().setToggleClickCount(clickCount);
	}
	
	/**
	 * Sets the number of rows that are to be displayed.
	 * This will only work if the tree is contained in a <code>JScrollPane</code>,
	 * and will adjust the preferred size and size of that scrollpane.
	 * <p>
	 * This is a bound property.
	 *
	 * @param newCount
	 *        the number of rows to display
	 * @beaninfo
	 *           bound: true
	 *           description: The number of rows that are to be displayed.
	 */
	public void setVisibleRowCount(int newCount) {
	
		getTree().setVisibleRowCount(newCount);
	}
	
	/**
	 * Selects the node identified by the specified path and initiates
	 * editing. The edit-attempt fails if the <code>CellEditor</code> does not allow
	 * editing for the specified item.
	 *
	 * @param path
	 *        the <code>TreePath</code> identifying a node
	 */
	public void startEditingAtPath(TreePath path) {
	
		getTree().startEditingAtPath(path);
	}
	
	/**
	 * Ends the current editing session.
	 * (The <code>DefaultTreeCellEditor</code> object saves any edits that are currently in progress on a cell.
	 * Other implementations may operate differently.)
	 * Has no effect if the tree isn't being edited.
	 * <blockquote>
	 * <b>Note:</b><br>
	 * To make edit-saves automatic whenever the user changes
	 * their position in the tree, use {@link #setInvokesStopCellEditing}.
	 * </blockquote>
	 *
	 * @return true if editing was in progress and is now stopped,
	 *         false if editing was not in progress
	 */
	public boolean stopEditing() {
	
		return getTree().stopEditing();
	}
	
	/**
	 * @return xml String
	 * @throws ParserConfigurationException
	 * @throws TransformerException
	 */
	public final String toXML() throws ParserConfigurationException, TransformerException {
	
		return getTree().toXML();
	}
	
	/**
	 * @param file
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws TransformerException
	 */
	public final void toXML(final File file) throws IOException, ParserConfigurationException, TransformerException {
	
		getTree().toXML(file);
	}
	
	/**
	 * Sent when the tree has changed enough that we need to resize
	 * the bounds, but not enough that we need to remove the
	 * expanded node set (e.g nodes were expanded or collapsed, or
	 * nodes were inserted into the tree). You should never have to
	 * invoke this, the UI will invoke this as it needs to.
	 */
	public void treeDidChange() {
	
		getTree().treeDidChange();
	}
}
